﻿// Original author contact info: Owen Emlen (owene_1998@yahoo.com)
// Note: other individuals may also have contributed to this code
// Project hosted on CodePlex.com as of 1/10/2009 at http://wpfimageviewer.codeplex.com
using System;
using System.IO;
using System.Linq;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Text;
using BrainTechLLC;
using BrainTechLLC.WPF;
using System.Windows.Data;
using System.Diagnostics;
using System.Windows.Controls;
using System.Windows.Threading;
using System.Windows;
using System.Collections.Specialized;
using DirectoryViewModels;
using System.Threading;
using BrainTechLLC.ThreadSafeObjects;

namespace BrainTechLLC.FolderExplorer
{
    public partial class FolderViewModel : BaseNotifyPropertyChangedUI
    {
        public static ThreadSafeCounter CurrentAsyncResizes = new ThreadSafeCounter();
        public bool _calculatingDirectorySize;

        public void CalcDirSizeAsync()
        {            
            if (_CorrectDirectorySize || _calculatingDirectorySize)
            {
                return;
            }
            
            ThreadStart ts = new ThreadStart(CalcDirSizeWorker);
            Thread t = new Thread(ts) { IsBackground = true, Priority = ThreadPriority.BelowNormal };
            t.Start();
        }

        private void CalcDirSizeWorker()
        {
            if (!_calculatingDirectorySize)
            {
                CurrentAsyncResizes.Increment();
                try
                {
                    CalcDirSize();

                    if (_abortCalcDirSize)
                    {
                        _CorrectDirectorySize = false;
                        _abortCalcDirSize = false;
                    }
                    else
                    {
                        _CorrectDirectorySize = true;
                        ClearFiles();
                    }
                }
                finally
                {
                    CurrentAsyncResizes.Decrement();
                }
            }
        }

        public void AbortCalcDirSize()
        {
            _abortCalcDirSize = true;
        }

        public long CalcDirSize()
        {
            if (_CorrectDirectorySize)
            {
                return _directorySize;
            }

            long dirSize = 0;

            if (!_calculatingDirectorySize)
            {
                _calculatingDirectorySize = true;

                try
                {
                    if (_abortCalcDirSize)
                    {
                        return dirSize;
                    }

                    try
                    {                        
                        var files = Files.ToList();

                        for (int n = 0; n < files.Count; n++)
                        {
                            var file = files[n];
                            try { dirSize += file.Length; }
                            catch { }
                        }
                    }
                    catch
                    {
                        // HEREHERE
                    }

                    var all = GetSubFoldersImmediate();
                    for (int n = 0; n < all.Count; n++)
                    {
                        if (_abortCalcDirSize)
                        {
                            break;
                        }
                        dirSize += all[n].CalcDirSize();

                        if (n % 3 == 0)
                        {
                            UpdateSize(dirSize);
                        }
                    }

                    UpdateSize(dirSize);                    
                }
                finally
                {
                    _calculatingDirectorySize = false;

                    if (_abortCalcDirSize)
                    {
                        _CorrectDirectorySize = false;
                        _abortCalcDirSize = false;
                    }
                    else
                    {
                        _CorrectDirectorySize = true;
                        ClearFiles();
                    }
                }
            }

            return dirSize;
        }

        private void UpdateSize(long dirSize)
        {
            try
            {
                Application.Current.Dispatcher.RunOnDispatcher(new OneParamDelegate((o) =>
                {
                    long size = (long)o;
                    DirectorySizeLong = size;
                }), DispatcherPriority.Normal, dirSize);
            }
            catch { }
        }
    }
}
